package code.part09_Lambda.P02_Lambda;

import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author: ZJT
 * @Time: 2021/8/2
 * @Description: Lambda常用写法
 */
public class P01_LambdaTest {

    @Test
    public void demo1() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("running1 .....");
            }
        };
        runnable.run();

        Runnable runnable2 = () -> {
            System.out.println("running2....");
        };
        runnable2.run();

        Runnable runnable3 = () -> System.out.println("running3....");
        runnable3.run();

    }

    @Test
    public void demo2() throws Exception {
        Callable<String> c1 = new Callable() {
            @Override
            public String call() throws Exception {
                return "mashibing";
            }
        };
        System.out.println(c1.call());

        Callable<String> c2 = () -> {
            return "mashibing2";
        };
        System.out.println(c2.call());

        Callable<String> c3 = () -> "mashibing3";
        System.out.println(c3.call());
    }

    @Test
    public void demo3() throws Exception {

        StudentDao sd1 = new StudentDao() {
            @Override
            public void insert(Student student) {
                System.out.println("student1");
            }
        };

        StudentDao sd2 = (student) -> {
            System.out.println("student2: " + student);
        };

        StudentDao sd3 = (Student student) -> System.out.println("student3: " + student);

        sd1.insert(new Student());
        sd2.insert(new Student());
        sd3.insert(new Student());
    }

    @Test
    public void demo4() throws Exception {
        TeacherDao td1 = new TeacherDao() {
            @Override
            public int get(Teacher teacher) {
                return 1;
            }
        };
        TeacherDao td2 = (teacher) -> {
            return 2;
        };
        TeacherDao td3 = (Teacher teacher) -> {
            return 3;
        };
        TeacherDao td4 = (teacher) -> 4;
        TeacherDao td5 = (Teacher teacher) -> 5;

        System.out.println(td1.get(new Teacher()));
        System.out.println(td2.get(new Teacher()));
        System.out.println(td3.get(new Teacher()));
        System.out.println(td4.get(new Teacher()));
        System.out.println(td5.get(new Teacher()));
    }

    /*
     * 在Java中提供了一系列的函数式接口，用来接受后续传入的逻辑，但是对输入和输出有要求
     * */

    /**
     * @author: ZJT
     * @Time: 2021/8/2
     * @Description: 一输入一输出
     */
    @Test
    public void demo5() throws Exception {
        Function<String,Integer> f1 = (str)->{return str.length();};
        System.out.println(f1.apply("abcdefg"));

    }

    /**
     * @author: ZJT
     * @Time: 2021/8/2
     * @Description: 无输入一输出
     */
    @Test
    public void demo6() throws Exception {

        Supplier<String> s1 = ()->{return "mashibing";};
        Supplier<String> s2 = ()->"mashibing2";
        System.out.println(s1.get());
        System.out.println(s2.get());
    }

    /**
     * @author: ZJT
     * @Time: 2021/8/2
     * @Description: 一输入无输出
     */
    @Test
    public void demo7() throws Exception {
        Consumer<String> c11 = (str) -> System.out.println(str);
        c11.accept("beijing");
        System.out.println("---------------");
    }

    /**
     * @author: ZJT
     * @Time: 2021/8/2
     * @Description: 两输入一输出
     */
    @Test
    public void demo8() throws Exception {
        BiFunction<String, String, Integer> bf = (a, b) -> a.length() + b.length();
        System.out.println(bf.apply("连老师", "好帅"));
    }


    /**
     * 直接调用函数
     */

    @Test
    public void demo9() throws Exception {

        Runnable runnable1 = ()->get();
        Runnable runnable2 = ()->exec();
//        Runnable runnable3 = ()->100;//Bad return type in lambda expression: int cannot be converted to void
        runnable1.run();
    }

    /**
     * @author: ZJT
     * @Time: 2021/8/2
     * @Description: 自定义
     */
    @Test
    public void demo10() throws Exception {

        LamabdInterface li1 = () -> get();
//        LamabdInterface li2 = ()->find();//Bad return type in lambda expression: String cannot be converted to int
        LamabdInterface li3 = () -> 100;
//        LamabdInterface li4 = ()->"abc";
        LamabdInterface li5 = () -> true ? 1 : 0;
        System.out.println(li1.get());

        List<String> list = Arrays.asList("a", "b", "c");
//        for (String s : list) {
//            System.out.println(s);
//        }
        list.forEach(System.out::println);
    }


    static int get() {
        return 1;
    }

    static String find() {
        return "find";
    }

    static void exec() {
        find();
    }
}
